<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>计算属性</title>
    <!--引入Vue-->
    <script type="text/javascript" src="./js/vue.js"></script>
</head>

<body>



    <!--

    我自己的总结:计算属性是data中的属性计算出来的,最终会出现在vue实例vm上,但是不会在vm_data上，_data收集的是data里面的属性，而计算属性不在data里面
    计算属性也是用数据代理原理的，当有人要修改vm中计算属性计算出来的属性值时，set就会被调用去找computed中的计算属性，进行修改，而且set也会引起计算属性依赖的data中的属性发生修改
    进而引起页面的修改
-->


    <!--计算属性:顾名思义就是计算出来的属性在vue中data里面的全部数据是属性，而计算出来的属性需要放在computed-->

    <!--
      1.计算属性:1.定义:要用的属性不存在，要通过已有属性计算得来，
      2.原理:底层借助了Objcet.definproperty方法提供的getter和setter
      3.get函数什么时候执行(1)当初读取时会执行一次（2）当依赖的数据发生改变时会被再次调用
      4.与method实现相比，内部哟暖存机制（复用）,效率更高，调试方便，
      5.计算属性最终会出现在vm上,直接读取使用即可
      6.如果计算属性要被修改，那必须写set函数去响应修改，且set中要引起计算时依赖的数据发生变化
    -->

    <div id="root">
        姓:<input type="text" v-model:value="firstname"> 名:
        <input type="text" v-model:value="lastname"> 姓名:

        <!--这里调用了3次计算属性但是只执行了一次 get()，剩下的来两次执行的缓存-->
        <!--所以和method相比计算属性最大的区别在于多次调用相同的计算属性只执行一次，剩下的执行暖存里面的，效率高-->
        <!--当计算属性的值发生变化时，才重新调用计算属性的get()方法-->
        <span>{{fullname}}</span>
        <span>{{fullname}}</span>
        <span>{{fullname}}</span>
    </div>

    <script>
        const vm = new Vue({
            el: "#root",
            //用data实现
            data: {
                firstname: "邓",
                lastname: '紫琪'
            },
            //计算属性
            computed: {
                //计算的过程为一个对象，计算属性的底层也用的数据代理
                fullname: {
                    //get的调用:（1）当有人读取vm身上的fullName时，get就会被调用去找computed中的fullname，且返回值作为fuallname的值 ，（2） 当所依赖的数据发生变化时         
                    get() {
                        //获取vm,计算属性中函数的this也是指向vue实例vm的
                        console.log(this)
                        console.log("get被调用了")
                        return this.firstname + this.lastname
                    },
                    //当vm上的fullName被修改时调用set(),value修改的值
                    //如果计算属性要被修改，那必须写set函数去响应修改，且set中要引起计算时依赖的数据发生变化
                    set(value) {
                        const arr = value.split('-')
                        this.firstname = arr[0]
                        this.lastname = arr[1]
                    }
                }

            },

        }); //计算属性最终会出现在vm上,直接读取使用即可
        console.log(vm) //vm中有fullname，但是vm._data中没有fullname，原因是：_data是收集data中的数据，而fullname是，
            //vm._data身上的firstname和lastname经过计算出来的,放在vm上，但是vm_data上收集不到
    </script>
</body>
</html>